<link rel="import" href="../../bower_components/paper-material/paper-material.html">
<link rel="import" href="../../bower_components/paper-button/paper-button.html">
<link rel="import" href="../../bower_components/paper-progress/paper-progress.html">
<link rel="import" href="../../bower_components/paper-styles/typography.html">
<link rel="import" href="../../bower_components/paper-listbox/paper-listbox.html">
<link rel="import" href="../app-form/app-form.html">
<script type="text/javascript" src="../network-create-fields.js" inline></script>

<dom-module id="network-create">
    <template>
        <style include="shared-styles forms single-page">
            #content {
                max-width: 900px;
            }

            paper-material {
                display: block;
                padding: 24px;
            }

            paper-progress {
                position: absolute;
                bottom: 85px;
                width: 100%;
                left: 0;
                right: 0;
            }

            :host>::slotted(paper-input-container) {
                padding-top: 16px;
                padding-bottom: 16px;
            }

            .dropdown-with-logos paper-item img {
                margin-right: 16px;
            }

            .single-head {
                @apply --network-page-head-mixin
            }
        </style>
        <div id="content">
            <paper-material class="single-head layout horizontal">
                <span class="icon">
                    <iron-icon icon="[[section.icon]]"></iron-icon>
                </span>
                <div class="title flex">
                    <h2>
                        Create Network
                    </h2>
                    <div class="subtitle">
                    </div>
                </div>
            </paper-material>
            <paper-material hidden$="[[hasCloudsWithNetworks]]">
                <p>To add a network you need to have an enabled Openstack, GCE or EC2 cloud in your account.
                    <br/> Add a cloud using the
                    <a href="/clouds/+add" class="blue-link regular">add cloud form</a>
                    or enable your Openstack or GCE clouds available in <a href="/dashboard" class="blue-link regular">dashboard</a>.
                </p>
            </paper-material>
            <paper-material hidden$=[[!hasCloudsWithNetworks]]>
                <div class="grid-row">
                    <paper-dropdown-menu class="dropdown-block l6 xs12 dropdown-with-logos" label="Select Cloud" horizontal-align="left">
                        <paper-listbox slot="dropdown-content" attr-for-selected="value" selected="{{selectedCloud::iron-select}}" class="dropdown-content">
                            <template is="dom-repeat" items="[[providers]]" as="provider">
                                <paper-item value="[[provider.id]]" disabled$="[[!_isOnline(provider.id, provider.state, model.clouds)]]">
                                    <img src="[[_computeProviderLogo(provider.provider)]]" width="24px">[[provider.title]]</paper-item>
                            </template>
                        </paper-listbox>
                    </paper-dropdown-menu>
                </div>
            </paper-material>
            <template is="dom-if" if="[[selectedCloud]]" restamp>
                <paper-material>
                    <app-form id="network_add" fields="{{fields}}" form="[[form]]" url="/api/v1/clouds/[[selectedCloud]]/networks" on-response="_handleCreateNetworkResponse"
                        on-error="_handleError" format-payload></app-form>
                </paper-material>
            </template>
        </div>
    </template>
    <script>
        Polymer({
            is: 'network-create',

            properties: {
                section: {
                    type: Object
                },
                model: {
                    type: Object
                },
                providers: {
                    type: Array
                },
                form: {
                    type: Object,
                    value: function () {
                        return {}
                    }
                },
                fields: {
                    type: Array,
                    value: function () { return [] }
                },
                networksFields: {
                    type: Array,
                    value: function () {
                        return NETWORK_CREATE_FIELDS;
                    }
                },
                hasCloudsWithNetworks: {
                    type: Boolean,
                    value: false
                },
                selectedCloud: {
                    type: String,
                    value: false
                },
            },
            observers: [
                '_cloudsChanged(model.clouds.*)',
                '_cloudChanged(selectedCloud)'
            ],
            listeners: {
                'format-payload': 'updatePayload'
            },
            _cloudsChanged: function (clouds) {
                var networkClouds = this.model && this.model.cloudsArray.filter(function (cloud) {
                    return ['openstack', 'gce', 'ec2', 'lxd'].indexOf(cloud.provider) > -1;
                });
                this.set('providers', networkClouds);
                this.set('hasCloudsWithNetworks', networkClouds && networkClouds.length > 0 ? true : false);
            },
            _computeProviderLogo: function (className) {
                var identifier = className.replace('_', '');
                return 'assets/providers/provider-' + identifier + '.png';
            },
            _isOnline: function (cloud, state, clouds) {
                return this.model.clouds[cloud] && this.model.clouds[cloud].state == 'online';
            },
            _cloudChanged: function (selectedCloud) {
                // clear to reset
                this.set('machineFields', []);
                var networkFields = [];
                if (this.selectedCloud) {
                    var cloudName = this.model.clouds[selectedCloud].provider;
                    networkFields = this.networksFields.find(function (c) {
                        return c.provider == cloudName;
                    });
                }
                // add cloud fields
                if (networkFields.fields)
                    this.set('fields', networkFields.fields);

                // add locations fields
                if (this.fieldIndexByName('region') > -1 || this.fieldIndexByName('availability_zone') > -1)
                    var fieldName = this.fieldIndexByName('region') > -1 ? 'region' : 'availability_zone';
                    if (cloudName == "ec2")
                        this.set('fields.'+this.fieldIndexByName(fieldName)+'.options', this.model.clouds[selectedCloud].locationsArray);
                    if (cloudName == "gce") {
                        var regionsArr = [], regions = [];
                        if (this.model.clouds[selectedCloud].locationsArray)
                            this.model.clouds[selectedCloud].locationsArray.forEach(function(l){
                                if (!regionsArr.includes(l.extra.region)) {
                                    regionsArr.push(l.extra.region);
                                    regions.push({name:l.extra.region, id:l.extra.region});
                                }
                            });
                        this.set('fields.'+this.fieldIndexByName(fieldName)+'.options', regions);
                    }
            },
            updatePayload: function () {
                if (this.fields.length) {
                    var payload = {},
                        provider = this.model.clouds[this.selectedCloud].provider;
                    payload['network'] = {};
                    // create network
                    for (var i = 0; i < this.fields.length; i++) {
                        if (this.fields[i].inPayloadGroup == "network")
                            payload.network[this.fields[i].name] = this.fields[i].value;
                    }
                    // create subnet
                    if ((this.fieldIndexByName('createSubnet') > -1 && this.fields[this.fieldIndexByName('createSubnet')].value == true) ||
                        (provider == "gce" && this.fields[this.fieldIndexByName('mode')].value == "custom")) {
                        payload.subnet = {};
                        for (var i = 0; i < this.fields.length; i++) {
                            if (this.fields[i].inPayloadGroup == "subnet")
                                payload.subnet[this.fields[i].name] = this.fields[i].name != "availability_zone" ? this.fields[i].value : this.model.clouds[this.selectedCloud].locations[this.fields[this.fieldIndexByName('availability_zone')].value].name;
                        }
                        // parse and format allocation pools if they exist
                        if (this.fieldIndexByName('allocation_pools') > -1 && this.fields[this.fieldIndexByName('allocation_pools')].value) {
                            var allocationPools = [], 
                                lines = this.fields[this.fieldIndexByName('allocation_pools')].value.split('\n');
                            lines.forEach(function (l) {
                                if (l && l.indexOf('-') > 0)
                                    allocationPools.push({
                                        start: l.replace(',', '').split('-')[0].trim(),
                                        end: l.replace(',', '').split('-')[1].trim()
                                    });
                                else
                                    allocationPools.push(l);
                            })
                            if (allocationPools.length){
                                payload.subnet['allocation_pools'] = allocationPools;
                            }
                        }

                        if (this.fieldIndexByName('disableGateway') > -1 && this.fields[this.fieldIndexByName('disableGateway')].value == true) {
                            delete payload.subnet['gateway_ip'];
                        }
                    }

                    this.set('form', payload);
                }
            },
            fieldIndexByName: function (name) {
                var field = this.fields.findIndex(function (f) {
                    return f.name == name;
                });
                return field;
            },
            _handleCreateNetworkResponse: function (e) {
                var response = JSON.parse(e.detail.xhr.response);
                this.dispatchEvent(new CustomEvent('go-to', { bubbles: true, composed: true, detail: {
                    url: '/networks'
                } }));

            },
            _handleError: function (e) {
                console.log(e);
                this.$.errormsg.textContent = e.detail.request.xhr.responseText;
                this.set('formError', true);
            },
            _goBack: function () {
                history.back();
            }
        });
    </script>
</dom-module>
